import com.sun.corba.se.spi.activation.Server;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.*;
import java.security.cert.TrustAnchor;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;

public class Project{
    public static void main(String[] args){
        MyInetAdress eg = new MyInetAdress();
        ServerFrame serverFrame = new ServerFrame();
        ClientFrame clientFrame = new ClientFrame();

    }
}

/*
InetAddress
    网络地址类
    1.通过域名获取主机信息
        InetAddress address = InetAddress.getByName("www.baidu.com");
    2.获取网络主机名(一帮就是域名)
        String name = address.getHostName();
    2.获取网络主机地址(IP地址)
        String addr = address.getHostAddress();
 */
class  MyInetAdress{
    final  boolean debug = false;
    MyInetAdress() {
        System.out.println("Init");
        try {
            InetAddress address;
            if(debug){
                address = InetAddress.getLocalHost();
            }else {
                address = InetAddress.getByName("www.baidu.com");
            }
            String name = address.getHostName();
            String addr = address.getHostAddress();
            System.out.println(name);
            System.out.println(addr);
        }catch (Exception e){
            System.out.println(e);
        }
    }
}

/*
1.ServerSocket
服务器
    创建服务器套接字，套接字绑定监听某个地址，通过accept获取到与客户端通信的套接字，
    使用多线程技术，为每一个客户端创建一个线程，通过套接字，进行读写；
    在Java中，可以使用数据流操作套接字。
    以下内容大致描述了服务器流程(单服务器)，需要注意的是涉及到IO操作的地方的异常处理

        ServerSocket server =  = new ServerSocket(6666);//创建服务器套接字,套接字绑定监听某个地址
        Socket socket = server.accept();//通过accept获取到与客户端通信的套接字
        //获取输入输出流
        DataInputStream in = new DataInputStream(socket.getInputStream());
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
        //流式操作进行通信
        out.writeUTF("This is server\r\n");
        String str = String.format("%c",(char)in.read());
        System.out.print(str);

2.Socket
客户端
    通过IP和端口创建与服务通信服务器套接字，使用输入输出流进行通信
        socket = new Socket(ip, port);//通过IP和端口创建与服务通信服务器套接字
        //获取输入输出流
        DataInputStream in = new DataInputStream(socket.getInputStream());
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
        //流式操作进行通信
        out.writeUTF("This is client\r\n");
        String str = String.format("%c",(char)in.read());
        System.out.print(str);

3.Timer
定时器
    自定义一个类继承于TimerTask，重写run函数，
    实例化一个Timer，通过schedule方法装载定时任务，同时设定执行延迟以及定时周期
class MyTimer extends TimerTask {//自定义一个类继承于TimerTask
    Timer timer;//实例化一个Timer
    public volatile long cnt = 5;
    public volatile long tag = 0;
    MyTimer(){
        timer = new Timer();
        timer.schedule(this,5000,100);//通过schedule方法装载定时任务，同时设定执行延迟以及定时周期
    }
    @Override
    public void run() {//重写run函数
        cnt += 1;

    }
}
 */
class TCPClient implements Runnable{
    Socket socket;
    BufferedWriter writer;
    BufferedReader reader;
    String ip;
    int port;
    DataInputStream in;
    DataOutputStream out;
    Thread t;
    TCPClient(){
        try {
            ip =InetAddress.getLocalHost().getHostAddress();
            port = 6666;
            init();
        }catch (Exception e ){

        }
        init();
    }
    TCPClient(String ip, int port){
        this.ip = ip;
        this.port = port;
        init();
    }
    void init(){
        t =new Thread(this);
        try {
            socket = new Socket(ip, port);
            if(socket.isConnected()){
                in = new DataInputStream(socket.getInputStream());
                out = new DataOutputStream(socket.getOutputStream());
                writer = new BufferedWriter(new OutputStreamWriter(out));
                reader = new BufferedReader(new InputStreamReader(in));
                out.writeUTF("This is client\r\n");
                t.start();
            }
        }catch (Exception e) {
        }
    }
    @Override
    public void run() {
        long pre = 0;
        long  crt = 0;
        String buf = null;
        char[] rev = new char[1024];
        while (true){
            try {

                String str = String.format("%c",(char)in.read());
                System.out.print(str);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class MyTimer extends TimerTask {
    Timer timer;
    public volatile long cnt = 5;
    public volatile long tag = 0;
    MyTimer(){
        timer = new Timer();
        timer.schedule(this,5000,100);
    }
    @Override
    public void run() {
        cnt += 1;

    }
}
class TCPServer implements Runnable{
    ServerSocket server;
    Socket socket;
    BufferedWriter writer;
    BufferedReader reader;
    String ip;
    int port;
    DataInputStream in;
    DataOutputStream out;
    Thread t;
    TCPServer(){
        t =new Thread(this);
        try {
            server = new ServerSocket(6666);
            t.start();

        }catch (Exception e ){

        }
    }

    @Override
    public void run() {
        try {
            socket = server.accept();
            in = new DataInputStream(socket.getInputStream());
            out = new DataOutputStream(socket.getOutputStream());
            writer = new BufferedWriter(new OutputStreamWriter(out));
            reader = new BufferedReader(new InputStreamReader(in));
            out.writeUTF("hello,this is server\r\n");
        } catch (IOException e) {
            e.printStackTrace();
        }

        char[] rev = new char[1024];

        while (true){
            try {
                System.out.print((char)in.read());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

class ClientFrame extends JFrame implements ActionListener{
    JTextField jtf;
    JTextArea jta;
    JButton buttonSend;
    TCPClient client;
    ClientFrame(){
        setTitle("client");
        jtf = new JTextField();
        jta = new JTextArea();
        buttonSend = new JButton("client");
        buttonSend.addActionListener(this);
        setSize(600,400);
        JPanel pSend = new JPanel();
        pSend.setLayout(new GridLayout(1,2));
        pSend.add(jtf);
        pSend.add(buttonSend);

        getContentPane().setLayout(new GridLayout(2,1));
        getContentPane().add(pSend);
        getContentPane().add(jta);
        client = new TCPClient("127.0.0.1",6666);
        //client = new TCPClient("192.168.0.133",8080);
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource().equals(buttonSend) ){
            String sendBuf = jtf.getText();
            try {
                if(sendBuf.isEmpty() == false)
                    client.out.writeUTF(sendBuf);
                    client.out.writeUTF("\r\n");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }
}

class ServerFrame extends JFrame implements ActionListener{
    JTextField jtf;
    JTextArea jta;
    JButton buttonSend;
    TCPServer server;
    ServerFrame(){
        setTitle("server");
        jtf = new JTextField();
        jta = new JTextArea();
        buttonSend = new JButton("server");
        buttonSend.addActionListener(this);
        setSize(600,400);
        JPanel pSend = new JPanel();
        pSend.setLayout(new GridLayout(1,2));
        pSend.add(jtf);
        pSend.add(buttonSend);

        getContentPane().setLayout(new GridLayout(2,1));
        getContentPane().add(pSend);
        getContentPane().add(jta);
        server = new TCPServer();
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == buttonSend){
            String sendBuf = jtf.getText();
            try {
                if(sendBuf.isEmpty() == false)
                    server.out.writeUTF(sendBuf);
                    server.out.writeUTF("\r\n");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }
}
